Software Project Implement

주석
프로그램 코드에서 명백하지 않은 부분을 이해하기 쉽게 기술
난독화된 구현을 명확하게 해주는 의사 코드(pseudo-code) 역할을 함
// one line notation
/* block notation */
/* 는 첫 번째 */을 통해 블록 주석은 끝나게 된다.

중첩된 주석은 전처리기 지시문 #if를 사용해서 구현할 수 있다.
전처리기 지시문
전처리기 지시문은 대부분의 언어와 무관하므로 최소한으로 사용하는 것이 좋으며
특히 매크로 사용은 제한하는 것이 좋음
- 매크로(define)
매크로 이름과 매크로 인수를 텍스트 정의로 확장해, 컴파일러 단위로 코드를 재사용하는 기법
매크로를 사용해서 프로그램에 권한을 부여할 수 있지만, 프로그램을 망칠 가능성이 크다.

매크로는 타입 개념 없이 무분별하게, 텍스트를 대체하기 때문에 네임스페이스, 스코프 또는
다른 언어 기능에 대한 저항력이 있다.

일부 라이브러리는 major와 같이 공통 이름을 갖는 매크로를 정의하고, 이를 같이 이용하기 위해서
#undef major와 같이 매크로를 해제해 주어야 함

매크로 이름이 겹치지 않게 하기 위해서 매우_긴_보기_좋지_않은_이름을_대문자로_사용 할것
C++에서 상수, inline 함수 및 constexpr처럼 매크로를 대체할 수 있는 수단이 있음
- 포함(include)
전처리기는 /usr/include, /usr/local/include 등과 같은 표준 include 디렉터리에서 헤더를 검색한다.
“”으로 감싼 헤더 파일에 대해서 현재 경로에서 우선 검색하고, 이후 표준 경로에서 검색한다.
(<>로 검색하고, 현재 경로를 검색 경로에 추가하는 것과 동일)
#include <iostream> // include
//
#include <another_project/more_functions.h>
#include "herberts_math_functions.hpp" //
표준 컴파일러 플래그를 이용해서 검색 경로 디렉터리 추가 가능
gcc -l <새로 추가할 디렉터리 경로> (윈도우는 /l)

C언어에서는 간단함을 유지하기 위해서 I/O와 같은 많은 기능을 핵심 언어에서 제외했다.
(대신 라이브러리로 제공<stdio.h>)
C++ 또한 이 설계 원칙을 따라 가능할 때마다, 표준 라이브러리에서 새로운 기능을 구현함
(따라서 대부분의 프로그램은 하나 이상의 헤더를 포함해야 함)
        포함 방지
간접적인 포함으로 인해 자주 사용되는 헤더 파일이 하나의 변역 단위에 여러번 포함될 수 있다.
금지된 반복을 피하기 위해 포함 방지(Include Guard) 처리를 한다.(첫 번째 include 만 수행됨)
#ifndef HERBERTS_MATH_FUNCTIONS_INCLUDE
#define HERBERTS_MATH_FUNCTIONS_INCLUDE
#include <cmath>
double sin(double x);
...
#endif // HERBERTS_MATH_FUNCTIONS_INCLUDE
프로젝트 이름 뿐만 아니라, 직접 또는 간접적으로 포함하는 모든 헤더의 이름은 고유 해야 함
포함방지를 컴파일러에게 지시할 수 있다.(#pragma once)
아래 코드는 위의 #ifndef와 #endif를 이용한 Include Guard 처리를 컴파일러가 지원한다.

#pragma는 표준은 아니지만, 대부분의 컴파일러에서 지원함
#pragma once
#include <cmath>
double sin(double x);
...
- 조건부 컴파일
전처리기는 분기를 위해 #if, #else, #elif, #endif 지시문을 제공한다.
#ifdef MACRO_NAME
#if defined MACRO_NAME // ifdef if defined
#ifndef MACRO_NAME
#if !defined MACRO_NAME // ifndef if !defiend
#elif ...
#else if ... // elif else if
이식성이 없는 라이브러리가 종종 존재한다.
윈도우에서만 사용할 수 있는 라이브러리(비주얼 스튜디오)

이와 같이  플랫폼에 의존하는 구현을 위해 다른 컴파일러를 위한 대체 코드 조각을 제공할 수 있다.
#ifdef _MSC_VER
...( )
#else
...(//MacOS )
#endif
모든 플랫폼에서 사용할 수 없는 새로운 언어 기능을 사용하기 위해서 조건부 컴파일이 필요하다.
아래의 코드는 이동 문법이 사용가능한 플랫폼은 이동 코드를 사용하고,
이동 문법이 사용 불가능한 플랫폼은 이식 가능한 코드로 이를 대체한다.
//
#ifdef MY_LIBRARY_WITH_MOVE_SEMANTICS
...( )
#else
...( , )
#endif
조건부 컴파일은 강력하지만, 비용이 크다.
소스 코드 및 테스트의 유지 보수가 어렵고 오류가 발생하기 쉽다.
잘 설계된 캡슐화를 통해 줄어들 수 있는 공통 인터페이스를 통해 다른 구현을 해서 방지
중첩 가능 주석문
#if 지시문을 사용해 코드 블록을 주석 처리
#if 0
...( )
#endif